// 精确计算方法
// 加法
export const add = (num1,num2) => {
  const calc = new Calc();
  return calc.add(num1,num2);
}
// 减法
export const sub = (num1, num2) => {
  const calc = new Calc();
  return calc.sub(num1,num2);
}
// 乘法
export const mul = (num1, num2) => {
  const calc = new Calc();
  return calc.mul(num1,num2);
}
// 除法
export const div = (num1, num2) => {
  const calc = new Calc();
  return calc.div(num1,num2);
}
class Calc{
  /**
   * 加法运算
   * @param {number} num1
   * @param {number} num2
   * @returns {*}
   */
  add(num1, num2) {
      num1 = Number(num1);
      num2 = Number(num2);
      let dec1, dec2, times;
      try { dec1 = this.countDecimals(num1)+1; } catch (e) { dec1 = 0; }
      try { dec2 = this.countDecimals(num2)+1; } catch (e) { dec2 = 0; }
      times = Math.pow(10, Math.max(dec1, dec2));
      const result = (this.mul(num1, times) + this.mul(num2, times)) / times;
      return this.getCorrectResult("add", num1, num2, result);
  }
  
  /**
   * 减法运算
   * @param {number} num1
   * @param {number} num2
   * @returns {number}
   */
  sub(num1, num2) {
      num1 = Number(num1);
      num2 = Number(num2);
      let dec1, dec2, times;
      try { dec1 = this.countDecimals(num1)+1; } catch (e) { dec1 = 0; }
      try { dec2 = this.countDecimals(num2)+1; } catch (e) { dec2 = 0; }
      times = Math.pow(10, Math.max(dec1, dec2));
      const result = Number((this.mul(num1, times) - this.mul(num2, times)) / times);
      return this.getCorrectResult("sub", num1, num2, result);
  }
  
  /**
   * 除法运算
   * @param {number} num1
   * @param {number} num2
   * @returns {number}
   */
  div(num1, num2) {
      num1 = Number(num1);
      num2 = Number(num2);
      let t1 = 0, t2 = 0, dec1, dec2;
      try { t1 = this.countDecimals(num1); } catch (e) { }
      try { t2 = this.countDecimals(num2); } catch (e) { }
      dec1 = this.convertToInt(num1);
      dec2 = this.convertToInt(num2);
      const result = this.mul((dec1 / dec2), Math.pow(10, t2 - t1));
      return this.getCorrectResult("div", num1, num2, result);
  }
  /**
   * 乘法运算
   * @param {number} num1
   * @param {number} num2
   * @returns {number}
   */
  mul(num1, num2) {
      num1 = Number(num1);
      num2 = Number(num2);
      let times = 0, s1 = num1.toString(), s2 = num2.toString();
      try { times += this.countDecimals(s1); } catch (e) { }
      try { times += this.countDecimals(s2); } catch (e) { }
      const result = this.convertToInt(s1) * this.convertToInt(s2) / Math.pow(10, times);
      return this.getCorrectResult("mul", num1, num2, result);
  }
  
  /**
   * 计算小数位的长度
   * @param {*} num
   * @returns {number}
   */
  countDecimals(num) {
      let len = 0;
      try {
          num = Number(num);
          let str = num.toString().toUpperCase();
          if (str.split('E').length === 2) { // 科学记数法
              let isDecimal = false;
              if (str.split('.').length === 2) {
                  str = str.split('.')[1];
                  if (parseInt(str.split('E')[0]) !== 0) {
                      isDecimal = true;
                  }
              }
              let x = str.split('E');
              if (isDecimal) {
                  len = x[0].length;
              }
              len -= parseInt(x[1]);
          } else if (str.split('.').length === 2) { // 十进制
              if (parseInt(str.split('.')[1]) !== 0) {
                  len = str.split('.')[1].length;
              }
          }
      } catch(e) {
          throw e;
      } finally {
          if (isNaN(len) || len < 0) {
              len = 0;
          }
          return len;
      }
  }
  
  /**
   * 将小数转成整数
   * @param {*} num
   * @returns {*}
   */
  convertToInt (num) {
      num = Number(num);
      let newNum = num;
      let times = this.countDecimals(num);
      let temp_num = num.toString().toUpperCase();
      if (temp_num.split('E').length === 2) {
          newNum = Math.round(num * Math.pow(10, times));
      } else {
          newNum = Number(temp_num.replace(".", ""));
      }
      return newNum;
  }
  
  /**
   * 确认我们的计算结果无误，以防万一
   * @param {string} type
   * @param {number} num1
   * @param {number} num2
   * @param {number} result
   * @returns {number}
   */
  getCorrectResult(type, num1, num2, result) {
      let temp_result = 0;
      switch (type) {
          case "add":
              temp_result = num1 + num2;
              break;
          case "sub":
              temp_result = num1 - num2;
              break;
          case "div":
              temp_result = num1 / num2;
              break;
          case "mul":
              temp_result = num1 * num2;
              break;
      }
        if (Math.abs(result - temp_result) > 1) {
            try {
                return Number(temp_result.toFixed(4));
            } catch (error) {
                return temp_result;
            }
        }
        try {
            return Number(result.toFixed(4));
        } catch (error) {
            return result;
        }
    }
}
// 保留两位小数,不进行舍入操作
export const formatDecimal = (num) => {
    let parts = num.toString().split(".");
    if (parts.length === 1) return num.toString() + ".00";
    if (parts[1].length === 1) return num.toString() + "0";
    return parts[0] + "." + parts[1].slice(0, 2);
};
// 功能暂未开放
export const notDeveloped = () => {
    uni.showToast({
        title: "功能暂未开放",
        icon: "error",
        duration: 2000,
    })
}
// 复制
export const copy = (str) => {
  uni.setClipboardData({
    data: str,
    success: function () {
        uni.showToast({
            title: "复制成功",
        });
    },
  });
};
// 切割字符，保留前 num 位和后 num 位（默认为4）
export const cut_address = (address, num=4) => {
    return address.slice(0, num) + "***" + address.slice(-num);
};